package com.example.docking.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.docking.dao.jindie.GenericDataItem;
import com.example.docking.dao.jindie.ResponseData;
import com.example.docking.dao.jindie.request.CommonOperateDao;
import com.example.docking.dao.jindie.request.PurInvoiceRequest;
import com.example.docking.dao.jindie.response.MaterialData;
import com.example.docking.dao.jindie.response.MaterialEntity_Invoice;
import com.example.docking.dao.jindie.response.SaveData;
import com.example.docking.dao.jindie.response.SupplierData;
import com.example.docking.dao.xky.*;
import com.example.docking.httpXKY.dao.BaseXKYListResponse;
import com.example.docking.httpXKY.dao.BaseXKYObjResponse;
import com.example.docking.httpXKY.httpSend.XKYClient;
import com.example.docking.service.impl.DataServiceImpl;
import com.example.docking.service.impl.SupplierServiceImpl;
import com.example.docking.util.Constants;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.smecloud.apigw.model.ApiResult;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

import static com.example.docking.httpXKY.httpSend.XKYClient.ERP_CODE;

/**
 * @author: tengguodong
 * @date: 2025/6/9
 */
@Slf4j
@Controller
public class XKYInvoiceOrderController {
    private final Gson gson = new Gson();

    @SneakyThrows
    public void selectInvoiceOrder() {
        // 1.查询发票订单列表
        List<InvoiceOrderItem> invoiceOrderList = selectInvoiceOrderList();
        log.info("发票订单列表：{}", gson.toJson(invoiceOrderList));
        if (invoiceOrderList.isEmpty()) {
            return;
        }
        for (InvoiceOrderItem invoiceOrderItem : invoiceOrderList) {
            if (invoiceOrderItem.getStatus().intValue() != 8) {
                log.info("跳过非已确认状态的发票订单，单号：{}, 当前状态：{}", invoiceOrderItem.getInvoiceNo(), invoiceOrderItem.getStatus());
                continue;
            }
            if (invoiceOrderItem.getSyncStatus().intValue() == 2) {
                log.info("跳过已同步的订单，单号：{}", invoiceOrderItem.getInvoiceNo());
                continue;
            }

            // 2.查询发票订单详情
            InvoiceOrderDetail invoiceOrderDetail = selectInvoiceOrderDetail(invoiceOrderItem.getInvoiceNo());
            log.info("发票订单详情：{}", JSON.toJSONString(invoiceOrderDetail));
            // 3.发票订单推送ERP
            DataServiceImpl service = new DataServiceImpl();
            PurInvoiceRequest purInvoiceRequest = new PurInvoiceRequest();
            setSupplier(purInvoiceRequest, invoiceOrderDetail);
            materialEntity(purInvoiceRequest, invoiceOrderDetail);
            purInvoiceRequest.setRemark("携客云同步，勿动" + invoiceOrderDetail.getInvXkNo());
            log.info("发票订单推送ERP：{}", JSON.toJSONString(purInvoiceRequest));
            ApiResult insertResult = service.InsertDataOne(Constants.PUR_INVOICE, new HashMap<>(), purInvoiceRequest);
            log.info("发票订单推送ERP结果：{}", JSON.toJSONString(insertResult));
            // 4.采购发票审核
            // auditPurInvoice(insertResult, service);
            // 5.回执发票订单同步状态
            updateSyncStatus(invoiceOrderDetail, insertResult);
        }
    }

    /**
     * 采购发票审核
     *
     * @param insertResult
     * @param service
     */
    private void auditPurInvoice(ApiResult insertResult, DataServiceImpl service) {
        ResponseData<SaveData> response = gson.fromJson(insertResult.getBody(), new TypeToken<ResponseData<SaveData>>() {
        }.getType());
        if (response.getErrcode() == 0) {
            log.info("采购发票推送ERP成功");
            List<String> ids = response.getData().getIds();
            CommonOperateDao commonOperateDao = new CommonOperateDao();
            commonOperateDao.setEntity_number("pur_invoice");
            commonOperateDao.setIds(ids);
            commonOperateDao.setOperate_type(Constants.AUDIT);
            try {
                ApiResult auditData = service.SelectDataAudit(Constants.COMMON_OPERATE, new HashMap<>(), commonOperateDao);
                ResponseData<SaveData> auditResponse = gson.fromJson(auditData.getBody(), new TypeToken<ResponseData<SaveData>>() {
                }.getType());
                if (auditResponse.getErrcode() == 0) {
                    log.info("审核采购发票成功, auditResponse = {}", auditResponse);
                } else {
                    log.error("审核采购发票失败. auditResponse: {}", auditResponse);
                    throw new RuntimeException(auditResponse.getErrcode() + ":" + auditResponse.getDescription());
                }
            } catch (Exception e) {
                log.error("Error occurred while auditing sales order", e);
                throw new RuntimeException(e);
            }
        }
    }

    @SneakyThrows
    private List<InvoiceOrderItem> selectInvoiceOrderList() {
        InvoiceOrderListParam invoiceOrderListParam = new InvoiceOrderListParam();
        invoiceOrderListParam.setErpCode(ERP_CODE);
        LocalDateTime now = LocalDateTime.now();
        //LocalDateTime now = LocalDateTime.of(2025, 7, 22, 16, 0, 0);
        long startDate = now.minusMinutes(60).toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
        long endDate = now.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
        invoiceOrderListParam.setStartDate(startDate);
        invoiceOrderListParam.setEndDate(endDate);
        String url = "https://openapi.xiekeyun.com/invoice/getNoList.json";
        String response = XKYClient.sendRequest(url, invoiceOrderListParam);
        BaseXKYListResponse<InvoiceOrderItem> xkyListResponse = JSONObject.parseObject(response, new TypeReference<BaseXKYListResponse<InvoiceOrderItem>>() {
        }.getType());
        return xkyListResponse.getDataList();
    }

    @SneakyThrows
    private InvoiceOrderDetail selectInvoiceOrderDetail(String invoiceNo) {
        InvoiceOrderDetailParam invoiceOrderDetailParam = new InvoiceOrderDetailParam();
        invoiceOrderDetailParam.setErpCode(ERP_CODE);
        invoiceOrderDetailParam.setInvoiceNo(invoiceNo);
        String url = "https://openapi.xiekeyun.com/invoice/getDetail.json";
        String response = XKYClient.sendRequest(url, invoiceOrderDetailParam);
        BaseXKYObjResponse<InvoiceOrderDetail> xkyObjResponse = JSONObject.parseObject(response, new TypeReference<BaseXKYObjResponse<InvoiceOrderDetail>>() {
        }.getType());
        return xkyObjResponse.getData();
    }

    @SneakyThrows
    private void setSupplier(PurInvoiceRequest purInvoiceRequest, InvoiceOrderDetail invoiceOrderDetail) {
        DataServiceImpl service = new DataServiceImpl();
        SupplierServiceImpl departmentService = new SupplierServiceImpl();
        SupplierData supplierData = departmentService.getSupplier(service, invoiceOrderDetail.getInnerVendorName());
        purInvoiceRequest.setSupplier_id(supplierData.getId());
    }

    @SneakyThrows
    private void materialEntity(PurInvoiceRequest purInvoiceRequest, InvoiceOrderDetail invoiceOrderDetail) {
        List<MaterialEntity_Invoice> materialEntities = new ArrayList<>();
        for (InvoiceProduct invoiceProduct : invoiceOrderDetail.getProdList()) {
            MaterialEntity_Invoice materialEntity = new MaterialEntity_Invoice();
            MaterialData materialData = getMaterialData(invoiceProduct);
            materialEntity.setMaterial_id(materialData.getId());
            materialEntity.setMaterial_number(materialData.getNumber());
            materialEntity.setMaterial_name(materialData.getName());
            materialEntity.setQty(invoiceProduct.getInvoicingQty());
            materialEntity.setUnit_id(materialData.getBase_unit_id());
            materialEntity.setBase_unit_number(materialData.getBase_unit_number());
            materialEntity.setPrice(invoiceProduct.getPrice());
            materialEntity.setTax_price(invoiceProduct.getTaxPrice());
            materialEntity.setCess(invoiceOrderDetail.getTaxRate().multiply(new BigDecimal("100")));
            materialEntities.add(materialEntity);
        }

        purInvoiceRequest.setMaterial_entity(materialEntities);
    }

    private MaterialData getMaterialData(InvoiceProduct invoiceProduct) {
        int page = 1; // 初始页码
        int pageSize = 10; // 每页记录数
        HashMap<String, String> map = new HashMap<>();
        map.put("page", String.valueOf(page));
        map.put("page_size", String.valueOf(pageSize));
        map.put("search", invoiceProduct.getProductCode());
        ApiResult detailMateria = null;
        try {
            DataServiceImpl service = new DataServiceImpl();
            detailMateria = service.SelectDataList(Constants.MATERIAL_PATH, map, "");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Type MateriaDataType = new TypeToken<ResponseData<GenericDataItem<MaterialData>>>() {
        }.getType();
        ResponseData<GenericDataItem<MaterialData>> detailMaterialData = gson.fromJson(detailMateria.getBody(), MateriaDataType);
        GenericDataItem<MaterialData> data = detailMaterialData.getData();
        List<MaterialData> rows = data.getRows();
        for (MaterialData row : rows) {
            if (Objects.equals(row.getNumber(), invoiceProduct.getProductCode())) {
                return row;
            }
        }
        return null;
    }

    @SneakyThrows
    private void updateSyncStatus(InvoiceOrderDetail invoiceOrderDetail, ApiResult insertResult) {
        Type type = new TypeToken<ResponseData<SaveData>>() {
        }.getType();
        ResponseData<SaveData> saveDataResponse = gson.fromJson(insertResult.getBody(), type);
        UpdateInvoiceSyncParam updateInvoiceSyncParam = new UpdateInvoiceSyncParam();
        updateInvoiceSyncParam.setErpCode(ERP_CODE);
        updateInvoiceSyncParam.setInvXkNo(invoiceOrderDetail.getInvXkNo());
        if (saveDataResponse.getErrcode() == 0) {
            // 成功
            updateInvoiceSyncParam.setInvErpNo(getErpCode(saveDataResponse));
            updateInvoiceSyncParam.setSyncStatus(2);
            updateInvoiceSyncParam.setPayExpiredDate(LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
        } else {
            updateInvoiceSyncParam.setSyncStatus(3);
        }
        String url = "https://openapi.xiekeyun.com/invoice/updateSyncInfo.json";
        String response = XKYClient.sendRequest(url, updateInvoiceSyncParam);
        log.info("response:{}", response);
    }

    private String getErpCode(ResponseData<SaveData> saveDataResponse) {
        SaveData saveData = saveDataResponse.getData();
        return saveData.getId_number_map().get(saveData.getIds().get(0));
    }

    @SneakyThrows
    public static void main(String[] args) {
        XKYInvoiceOrderController xkyInvoiceOrderController = new XKYInvoiceOrderController();
        xkyInvoiceOrderController.selectInvoiceOrder();


        /*UpdateInvoiceSyncParam updateInvoiceSyncParam = new UpdateInvoiceSyncParam();
        updateInvoiceSyncParam.setErpCode(ERP_CODE);
        updateInvoiceSyncParam.setInvXkNo("5317531689741140");
        // 成功
        updateInvoiceSyncParam.setInvErpNo("CGFP-20250723-00001");
        updateInvoiceSyncParam.setSyncStatus(2);
        updateInvoiceSyncParam.setPayExpiredDate(LocalDateTime.now().plusDays(7).toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
        String url = "https://openapi.xiekeyun.com/invoice/updateSyncInfo.json";
        String response = XKYClient.sendRequest(url, updateInvoiceSyncParam);
        log.info("response:{}", response);*/

    }
}
